﻿/** @file Char.h
	@brief	文字クラス定義ファイル。
*/
#ifndef STRAY_CHAR_H
#define STRAY_CHAR_H

#include "../Common.h"
#include "../SmartPtr/UniquePtr.h"
#include "Encoding.h"

namespace Stray {

class CharImpl;

/** @class Char
	@brief	文字クラス
			実装クラスの生成にはnew(std::nothrow)を使用しているので、コンストラクタでpImple_のnewに失敗しても例外を投げない。
			生成に失敗した場合、各メソッドは動作しないで呼び出し元にもどる。
			戻り値があるものは、符号あり整数は-1、符号なし整数、bool値、ポインタを返すものは0、
			それ以外は規定のコンストラクタで生成されたオブジェクトを返す。
*/
class Char
{
public:
	/**
		@brief	コンストラクタ
	*/
	Char();
	Char(const char* code);	//!< 文字列リテラルで初期化。エンコードは処理系にあわせる。
	Char(const char code);
	Char(const wchar_t* code); //!< 文字列リテラルで初期化。エンコードは処理系にあわせる。
	Char(const wchar_t code);

	/**
		@brief	デストラクタ
	*/
	~Char();

	/**
		@brief	コピーコンストラクタ
	*/	
	Char(const Char& rhs);

	/**
		@brief	代入演算子	
	*/
	Char& operator =(const Char& rhs);

	/**
		@brief	実装クラスのインスタンスが生成されたかどうか確認。生成されていればture、失敗していればfalseを返す。
	*/
	bool isValid() const;

	/**
		@brief char型文字列に変換
	*/
	const char* toChar();

	/**
		@brief wchar_t型文字列に変換
	*/
	const wchar_t* toWchar();

	/**
		@brief	指定したエンコードでの文字コードのバイトサイズを取得。
		@param	encoding エンコード方法
		@return	文字サイズ。
	*/
	size_t getSize(Encoding encoding) const;

	/**
		@brief	エンコードを指定して文字コードを取得
		@param[in]	encoding エンコード方法
		@param[out]	pOut 出力するコードを受け取る変数のポインタ
	*/
	void getCode(void* pOut, Encoding encoding) const;

	/**
		@brief	エンコードを指定して文字を設定
		@param	encoding エンコード方法
		@param	pCode 文字コードへのポインタ
	*/
	void set(const void* pCode, Encoding encoding);

	/**
		@brief	char型で文字を設定。エンコード方法は処理系のデフォルト。
		@param	pCode セットする文字コードへのポインタ
	*/
	void set(const char* pCode);

	/**
		@brief	wchar_t型で文字を設定。エンコード方法は処理系のデフォルト。
		@param	pCode セットする文字コードへのポインタ
	*/
	void set(const wchar_t* pCode);

	/**
		@brief	文字の比較。等しいならtrueを返す。違うならfalseを返す。
		@param	rhs 比較する文字
		@return	結果
	*/
	bool equals(const Char& rhs) const;
private:
	typedef Stray::UniquePtr<CharImpl>::type ImplPtr;
	ImplPtr pImpl_; //<! 実装
};

/**
	@brief	Charの比較用演算子。lhs.equals(rhs)と同等。
	@param	lhs 比較する文字
	@param	rhs	比較する文字
	@return 等しいならtrue。
*/
bool operator ==(const Char& lhs, const Char& rhs);

}

#endif